package com.demo.webflux.simple3;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import com.demo.webflux.domain.Book;

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.util.function.Tuple2;

@Service
public class BookService {

	@Autowired
	private ReactiveSpringDataMongoBookRepository rxBookRepository;

	public Mono<Book> updateBookYearByTitle(Mono<String> title, Mono<Integer> newPublishYear) {
		// 由于我们在收到标题之后才订阅新的出版年份，因此执行时间：PT3.475S
		return rxBookRepository.findOneByTitle(title)
					.flatMap(book -> newPublishYear
							.flatMap(year -> {
								book.setPublishYear(year);
								return rxBookRepository.save(book);
							}));
	}

	public Mono<Book> updateBookYearByTitle2(Mono<String> title, Mono<Integer> newPublishYear) {
		// 我们可以在开头订阅两个流，一旦两个流都准备就绪，我们就可以更新数据，执行时间：PT2.226S
		return Mono.zip(title, newPublishYear)
					.flatMap((Tuple2<String, Integer> data) -> {
						String titleVal = data.getT1();
						Integer yearVal = data.getT2();
						return rxBookRepository.findOneByTitle(Mono.just(titleVal))
									.flatMap(book -> {
										book.setPublishYear(yearVal);
										return rxBookRepository.save(book);
									});
					});
	}

	public Mono<Book> updateBookYearByTitle3(Mono<String> title, Mono<Integer> newPublishYear) {
		// 其实在出版年份请求仍在进行中但标题值已经存在时，我们也可以开始加载图书实体，执行时间：PT3.022S
		return Mono.zip(rxBookRepository.findOneByTitle(title), newPublishYear)
				.flatMap((Tuple2<Book, Integer> data) -> {
					Book bookVal = data.getT1();
					Integer yearVal = data.getT2();
					bookVal.setPublishYear(yearVal);
					return rxBookRepository.save(bookVal);
				});
	}

	public Flux<Book> findByAuthor(String author, Pageable pageable) {
		return rxBookRepository.findByAuthor("zhangsan", PageRequest.of(1, 5)); // 请求第二页的5个元素
	}

}
